export class history<T>
{
    stor:GameDataStorage<T>
    
    public list = new Map<string,T>()

    public get_count:number
    public get_time:number

    public error_out:boolean
    public use_list:boolean

    public when_no_get:(<A>(key:string,other?:A) => T)|undefined

    constructor(name:string,when_no_get?:<A>(key:string,other?:A) => T,use_list:boolean = false,error_out:boolean = true,get_count:number = 3,get_time:number = 200)
    {
        this.stor = storage.getGroupStorage<T>(name)
        this.get_count = get_count
        this.get_time = get_time
        this.error_out = error_out
        this.use_list = use_list
        this.when_no_get = when_no_get
    }
    public async get<A>(key:string,other?:A)
    {
        if(this.use_list && this.list.has(key))
        {
            return this.list.get(key)!
        }
        for(let i = 0;i < this.get_count;i++)
        {
            try
            {
                let data = await this.stor.get(key)
                if(data)
                {
                    this.list.set(key,data.value)
                    return data.value
                }
            }
            catch(e)
            {
                if(this.error_out)
                {
                    world.say(`[Error]${e}`)
                }
                console.log(`[Error]\nsay:${e}\nfrom:${this.stor.key}\nkey:${key}`)
            }
            await sleep(this.get_time)
        }
        if(this.when_no_get)
        {
            const now = this.when_no_get<A>(key,other)
            this.set(key,now)
            return now
        }
        return null
    }
    public async set(key:string,value:T)
    {
        this.list.set(key,value)
        for(let i = 0;i < this.get_count;i++)
        {
            try
            {
                await this.stor.set(key,value)
                return
            }
            catch(e)
            {
                if(this.error_out)
                {
                    world.say(`[Error]${e}`)
                }
                console.log(`[Error]\nsay:${e}\nfrom:${this.stor.key}\nkey:${key}`)
            }
            await sleep(this.get_time)
        }
    }
    public async delete(key:string)
    {
        this.list.delete(key)
        try
        {
            await this.stor.remove(key)
        }
        catch(e)
        {
            if(this.error_out)
            {
                world.say(`[Error]${e}`)
            }
            console.log(`[Error]\nsay:${e}\nfrom:${this.stor.key}\nkey:${key}`)
        }
    }
}